package controllers;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import play.cache.Cache;
import play.mvc.Before;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: Cyril
 * Date: 06.08.11
 * Time: 22:48
 * To change this template use File | Settings | File Templates.
 */
public class CustomSecure extends MenuBuilder {

    public static void login() throws Throwable {
        UserService userService = UserServiceFactory.getUserService();
        if (userService.isUserLoggedIn()) {
            User user = userService.getCurrentUser();
            Cache.delete(session.getId() + "-perms");
            session.put("username", user.getNickname());
            redirectToOriginalURL();
        }
        redirect(userService.createLoginURL(request.url));
    }


    @Before(unless={"login", "authenticate", "logout"})
    static void checkAccess() throws Throwable {
        // Authent
        if(!session.contains("username")) {
            session.put("url", "GET".equals(request.method) ? request.url : "/"); // seems a good default
            login();
        }
        // Checks
        Check check = getActionAnnotation(Check.class);
        if(check != null) {
            check(check);
        }
        check = getControllerInheritedAnnotation(Check.class);
        if(check != null) {
            check(check);
        }
        UserChecker.checkUser();
    }

    private static void check(Check check) throws Throwable {
        if ( ! check( check.value() ) ) {
            if (UserServiceFactory.getUserService().isUserLoggedIn())
                forbidden();
            else
                redirect("/login");
        }
    }

    public static boolean check(String[] check) throws Throwable {
        List<String> perms = Cache.get(session.getId() + "-perms", List.class);
        if (perms == null) {
            UserService userService = UserServiceFactory.getUserService();
            perms = userService.isUserLoggedIn() && userService.isUserAdmin() ?
                    Arrays.asList( "admin" ) : Collections.<String>emptyList();
            Cache.set(session.getId() + "-perms", perms);
        }
        return perms.containsAll( Arrays.asList(check) );
    }

    public static void logout() throws Throwable {
        session.clear();
        response.removeCookie("rememberme");
        flash.success("secure.logout");
        redirect("/");
    }

    // ~~~ Utils

    static void redirectToOriginalURL() throws Throwable {
        String url = session.get("url");
        if(url == null) {
            url = "/";
        }
        redirect(url);
    }

}
